package cn.edu.nuaa.aadl2.generatorC.utils

import org.osate.aadl2.Feature
import org.osate.aadl2.impl.DataTypeImpl
import org.osate.aadl2.impl.SubprogramImplementationImpl
import org.osate.aadl2.impl.DataImplementationImpl
import org.osate.aadl2.impl.ParameterImpl
import org.eclipse.emf.common.util.EList
import org.osate.aadl2.ComponentClassifier
import org.osate.aadl2.Classifier
import org.osate.aadl2.impl.DataAccessImpl
import org.osate.aadl2.impl.SubprogramAccessImpl
import org.osate.aadl2.SubprogramClassifier
import cn.edu.nuaa.aadl2.generatorC.utils.StringUtils
import org.osate.aadl2.impl.NamedElementImpl
import static extension cn.edu.nuaa.aadl2.generatorC.utils.StringUtils.*
import java.util.List

class ParamUtils {
	
	def static convert(String str){
		if(str==null)
			return "";
		return str.toLowerCase.replace(".","_")
	}
//将aadl中的数据类型转化为c语言对应的数据类型
def static transDataAADL2C(String aadl){
	switch(aadl){
		case "Character":return "char"
		case "Boolean":return "bool"
		case "Integer":return "int"
		case "Integer_32":return "int"
		case "Unsigned_16":return "short"
		case "Unsigned_32":return "int"
		case "Unsigned_64":return "long"
		case "Float":return "float"
		case "Double":return "double"
		case "void":return "void"
		default:return aadl.convertNo2Low
	}
}	
	
//获取函数返回值类型 by zong
def static getReturnType(Classifier classifier){
	 var returnType="";
	 //获取所有的参数列表
        var features=classifier.allFeatures
        //初始值设置为空
        var result="void";
        for(var i=0;i<features.size;i++){
    	  var oneFeature=features.get(i);
    	  var type=features.get(i).getFeatureClassifier();
   	        //对参数向上造型为ParameterImpl，并且如果获取到的out为true，就直接返回类型名称。
          	if(oneFeature instanceof ParameterImpl&&type instanceof NamedElementImpl){
          	   if((oneFeature as ParameterImpl).out){
          	   	   returnType=(type as NamedElementImpl).name; 
          	   	   return transDataAADL2C(returnType).convertNo2Low;
          	   }
          	}else{//否则，为了防止还有其他类型导致造型失败，返回void
          		return transDataAADL2C(result).convertNo2Low;
          	}
    	  }
    	  //如果没有遇到任何参数为out，那么返回值为void
           return transDataAADL2C(result).convertNo2Low;
}
	
//获取函数返回值类型(已过时) by zong
@Deprecated
def static getReturnType(Feature feature){
	 var paras="";
	 //获取所有的参数列表
        var features=feature.classifier.allFeatures
        //初始值设置为空
        var result="void";
        for(var i=0;i<features.size;i++){
    	  var oneFeature=features.get(i);
    	  var type=features.get(i).getFeatureClassifier();
   	        //对参数向上造型为ParameterImpl，并且如果获取到的out为true，就直接返回类型名称。
          	if(oneFeature instanceof ParameterImpl&&type instanceof DataTypeImpl){
          	   if((oneFeature as ParameterImpl).out){
          	   	  return (type as DataTypeImpl).name; 
          	   }
          	}else{//否则，为了防止还有其他类型导致造型失败，返回void
          		return result;
          	}
    	  }
    	  //如果没有遇到任何参数为out，那么返回值为void
           return result;
}
//获取所有的dataAccess by zong
def static getAllDataAccess(Classifier classifier){
	 var paras="";
        //获取参数列表
        var features=classifier.allFeatures
        var result="";
        //遍历参数列表将参数列表中的out类型除去
        for(var i=0;i<features.size;i++){
        	  var oneFeature=features.get(i);
          //如果参数向下造型成功
          if(!(oneFeature instanceof DataAccessImpl)){//如果这个参数的类型是不是dataAccess,就删除
                 features.remove(i);
                 i--;
          }else{
          	var name=oneFeature.name
          	var type=oneFeature.getFeatureClassifier()
          	var typeName=(type as DataImplementationImpl).name
          	if(i!=features.size-1){
          		result+="extern "+typeName.replace(".","_")+" "+name+";\n"
          	}else{
          		result+="extern "+typeName.replace(".","_")+" "+name+";"
          	}
          	
          }
       }
       return result.convertNo2Low;
}

//获取所有的subProgram by zong
def static getAllSubProgram(Classifier classifier){
	 var paras="";
        //获取参数列表
        var features=classifier.allFeatures
        var result="";
        //遍历参数列表将参数列表中的out类型除去
        for(var i=0;i<features.size;i++){
        	  var oneFeature=features.get(i);
          //如果参数向下造型成功
          if(!(oneFeature instanceof SubprogramAccessImpl)){//如果这个参数的类型是不是dataAccess,就删除
                 features.remove(i);
                 i--;
          }else{
            var name=oneFeature.name //获取这个subprogram的名称
          	var type=oneFeature.getFeatureClassifier()//获取这个subprogram的classifier
//          	var classifier=(type as SubprogramClassifier).allFeatures;//将获取到的classifier造型成为SubprogramClassifier，并获取全部参数，虽然不知道对不对
          	var subProgramClassifier=(type as SubprogramClassifier)
          	//获取返回值类型
          	var returnType=getReturnType(subProgramClassifier)
          	//获取参数列表
          	var paramsList=getParasList(subProgramClassifier)
          	
          	if(i!=features.size-1){
          	result+="extern "+returnType.convertNo2Low+" "+name+"("+paramsList+");"+"\n"
          	}
          	else{
          	result+="extern "+returnType.convertNo2Low+" "+name+"("+paramsList+");"	
          	}
          }
       }
       return result;
}

//获取没有类型的参数列表
def static getParasListWithoutType(Classifier classifier){
       //获取带有参数类型的参数列表
//      var paras = getParasList(classifier.allFeatures);
      var paras = getParasList(classifier);
       if(paras.contains("unionContOrder")&&paras.contains("ucMisNum")){
       	var a=0;
       	var b=1;
       }
       var result="";
       if(!paras.equals("")){//如果这个子程序有参数
       	   //将每个参数取出来存入链表
       var parasList=paras.split(",");
       for(var i=0;i<parasList.size;i++){
       	//将每个参数用空格分隔，只取出后面的参数名称
       	  var tmp=parasList.get(i).split(" ");
       	  if(i==parasList.size-1){
       	  	result+=tmp.get(1);
       	  }else{
       	  	result+=tmp.get(1)+",";
       	  }
       }
       return result.convertNo2Low;
       }
       else{
       	return result;
       }
    
    }
//这个是拓展接口，可以用，但是目前没用到 by zong 
def static getParasList(EList<Feature> features){
	  var result="";
        //遍历参数列表将参数列表中的out类型除去
        for(var i=0;i<features.size;i++){
        	  var oneFeature=features.get(i);
          //如果参数向下造型成功
          if(oneFeature instanceof ParameterImpl){//如果这个参数的类型是parameter就留下 
          	//如果这个参数的类型是返回值
          	 if((oneFeature as ParameterImpl).out){
          	 	features.remove(i);
          	 	i--;
          	 }
          }else if(oneFeature instanceof DataAccessImpl){//如果这个参数的类型不是parameter直接就把这个参数删去         
          	features.remove(i);
          	i--;
          }else if(oneFeature instanceof SubprogramAccessImpl){
           features.remove(i);
           i--;
          }
        }
        //遍历输入参数链表
        for(var i=0;i<features.size;i++){
                  var oneFeature=features.get(i);
		          var paraName=features.get(i).name;
		          
		          //获取参数类型
		    	  var type=features.get(i).getFeatureClassifier();
		    	  var typeName="";
		    	  //如果是正确的参数类型
		    	  if(type instanceof NamedElementImpl){
		    		typeName=(type as NamedElementImpl).name; 
		    		typeName=transDataAADL2C(typeName);
		    	  }

		    	  else{
		    	  	typeName=type.toString();
		    	  }	    	
		    	  //如果是最后一个的话  ,同时防止出现 function( , )的情况出现
		    	  if(!typeName.equals("")&&!paraName.equals("")){ 	  	
			    	  if(i==features.size-1){
			    	  result+=typeName.convertNo2Low+" "+paraName;
			    	  }else{ 	  	
			    	  result+=typeName.convertNo2Low+" "+paraName+",";
			          }
		    	  }
		    	  
        }
           return result.convertNo2Low;
}

//获取参数列表 by zong
def static getParasList(Classifier classifier){
        var paras="";
        //获取参数列表
        var features=classifier.allFeatures
        var result="";
        //遍历参数列表将参数列表中的out类型除去
        for(var i=0;i<features.size;i++){
        	  var oneFeature=features.get(i);
          //如果参数向下造型成功
          if(oneFeature instanceof ParameterImpl){//如果这个参数的类型是parameter就留下 
          	//如果这个参数的类型是返回值
          	 if((oneFeature as ParameterImpl).out){
          	 	features.remove(i);
          	 	i--;
          	 }
          }else if(oneFeature instanceof DataAccessImpl){//如果这个参数的类型不是parameter直接就把这个参数删去         
          	features.remove(i);
          	i--;
          }else if(oneFeature instanceof SubprogramAccessImpl){
           features.remove(i);
           i--;
          }
        }
        //遍历输入参数链表
        for(var i=0;i<features.size;i++){
                  var oneFeature=features.get(i);
		          var paraName=features.get(i).name;
		          
		          //获取参数类型
		    	  var type=features.get(i).getFeatureClassifier();
		    	  var typeName="";
		    	  //如果是正确的参数类型
		    	  if(type instanceof NamedElementImpl){
		    		typeName=(type as NamedElementImpl).name; 
		    		typeName=transDataAADL2C(typeName);
		    	  }
//		    	  //如果是下面这两种类型就先忽略
//		    	  else if(type instanceof DataImplementationImpl){
//		            typeName="";
//		            paraName="";
//		    	  }
//		    	  else if(type instanceof SubprogramImplementationImpl){
//		    	  	typeName="";
//		            paraName="";
//		            
////		            continue;
//		            //这里需要一个中止本次循环的操作
//		    	  }
		    	  //下面这个地方是为了防止还有其他类型，便于调试的，如果确认没有最后可以和
		    	  //上面两个合在一起
		    	  else{
		    	  	typeName=type.toString();
		    	  }	    	
		    	  //如果是最后一个的话  ,同时防止出现 function( , )的情况出现
		    	  if(!typeName.equals("")&&!paraName.equals("")){
		    	  	
//		    	  	if(paraName.equals("ucMisNum")){
//		    	  		var df=1;
//		    	  	} 	  	
			    	  if(i==features.size-1){
			    	  	if(typeName.equals("ucMisNum.impl")){
			    	  		var a=0;
			    	  	}
			    	  result+=typeName.convertNo2Low+" "+paraName;
			    	  }else{
			    	  	
			    	  	if(typeName.equals("ucMisNum.impl")){
			    	  		var a=0;
			    	  	}
			    	  	
			    	  result+=typeName.convertNo2Low+" "+paraName+",";
			          }
		    	  }
		    	  
        }
           return result.convertNo2Low;
    }

//获取参数列表(已过时) by zong
@Deprecated
 def static getParasList(Feature feature){
        var paras="";
        //获取参数列表
        var features=feature.classifier.allFeatures
        var result="";
        //遍历参数列表将参数列表中的out类型除去
        for(var i=0;i<features.size;i++){
        	  var oneFeature=features.get(i);
          //如果参数向下造型成功
          if(oneFeature instanceof ParameterImpl){
          	//如果这个参数的类型是返回值
          	 if((oneFeature as ParameterImpl).out){
          	 	features.remove(i);
          	 }
          }
        }
        //遍历输入参数链表
        for(var i=0;i<features.size;i++){
                  var oneFeature=features.get(i);
		          var paraName=features.get(i).name;
		          //获取参数类型
		    	  var type=features.get(i).getFeatureClassifier();
		    	  var typeName="";
		    	  //如果是正确的参数类型
		    	  if(type instanceof NamedElementImpl){
		    		typeName=(type as NamedElementImpl).name; 
		    	  }
		    	  //如果是下面这两种类型就先忽略
//		    	  else if(type instanceof DataImplementationImpl){
//		            typeName="";
//		            paraName="";
//		    	  }
//		    	  else if(type instanceof SubprogramImplementationImpl){
//		    	  	typeName="";
//		            paraName="";
//		            
////		            continue;
//		            //这里需要一个中止本次循环的操作
//		    	  }
		    	  //下面这个地方是为了防止还有其他类型，便于调试的，如果确认没有最后可以和
		    	  //上面两个合在一起
		    	  else{
		    	  	typeName=type.toString();
		    	  }	    	
		    	  //如果是最后一个的话  ,同时防止出现 function( , )的情况出现
		    	  if(!typeName.equals("")&&!paraName.equals("")){
			    	  if(i==features.size-1){
			    	  result+=typeName+" "+paraName;
			    	  }else{
			    	  	result+=typeName+" "+paraName+",";
			          }
		    	  }
		    	  
        }
           return result;
//        因为要计数，所以改成上面这种方式
//        for(oneFeature:features){
//          val paraName=oneFeature.name;
//    	  val type=oneFeature.getFeatureClassifier();
//    	  var typeName="";
//    	  if(type instanceof DataTypeImpl){
//    		typeName=(type as DataTypeImpl).name; 
//    	  }else{
//    	  	typeName=type.toString();
//    	  }
//    	  result+=typeName+" "+paraName;
//        }
    }
    
//获取一个参数by zong
def static getParam(Classifier classifier){
	
}
 //获取返回值by zong
def static getReturnValue(EList<Feature> features){	
        //初始值设置为空
        var result="";
        for(var i=0;i<features.size;i++){
    	  var oneFeature=features.get(i);
    	  var type=features.get(i).getFeatureClassifier();
   	        //对参数向上造型为ParameterImpl，并且如果获取到的out为true，就直接返回类型名称和变量名称。
          	if(oneFeature instanceof ParameterImpl&&type instanceof NamedElementImpl){
          	   if((oneFeature as ParameterImpl).out){
//          	   	  return (type as DataTypeImpl).name+" "+oneFeature.name; 
						return oneFeature.name; 
          	   }
          	}else{//否则，为了防止还有其他类型导致造型失败，返回“”
          		return result;
          	}
    	  }
    	  //如果没有遇到任何参数为out，那么返回值为“”
           return result;
    }
   
    
//获取返回值by zong
def static getReturnValue(Classifier classifier){	
	 //获取所有的参数列表
        var features=classifier.allFeatures
        //初始值设置为空
        var result="";
        for(var i=0;i<features.size;i++){
    	  var oneFeature=features.get(i);
    	  var type=features.get(i).getFeatureClassifier();
   	        //对参数向上造型为ParameterImpl，并且如果获取到的out为true，就直接返回类型名称和变量名称。
          	if(oneFeature instanceof ParameterImpl&&type instanceof NamedElementImpl){
          	   if((oneFeature as ParameterImpl).out){
//          	   	  return (type as DataTypeImpl).name+" "+oneFeature.name; 
						return oneFeature.name; 
          	   }
          	}else{//否则，为了防止还有其他类型导致造型失败，返回“”
          		return result;
          	}
    	  }
    	  //如果没有遇到任何参数为out，那么返回值为“”
           return result;
    }
   
}